home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / archiver / lzhsourc.lzh / LZH.SRC / HUFST.S < prev    next >
Text File  |  1992-07-02  |  38KB  |  1,667 lines

  1.  
  2. ;-----------------------------------------------------------------------
  3. ; This is a assembler-version of some parts of huf.c
  4. ;
  5. ; Coded in may 1990 by Thomas Quester
  6. ; Some of this code is reassembled C
  7. ;
  8. ; To get rid of scaling the array's, the values of dad, son, lson, rson
  9. ; hold the double value
  10. ;
  11. ;------------------------------------------------------------------------
  12.  
  13.  
  14.  
  15. ; -----------------------------------------------------------------------
  16. ;        Externals
  17. ; -----------------------------------------------------------------------
  18.  
  19.         export Decode
  20.         export Encode
  21.         import EncodeEn
  22. ;        export EncodePo
  23. ;        export GetBit
  24. ;        import GetByte
  25.         import InitTree
  26.         export PatchF
  27. ;        export Putcode
  28.         export StartHuf
  29.         import _StdErrF
  30.         import _StdOutF
  31.         export blkcnt
  32.         export blocksize
  33. ;        import code_buf
  34.         export codesize
  35.         export crc
  36.         export crc_getc
  37.         export crctbl
  38. ;        import d_code
  39. ;        import d_len
  40.         export dad
  41.         import error
  42.         import ferror
  43.         import fgetc
  44.         import ungetc
  45.         export flg_n
  46.         import fputc
  47. ;        export freq
  48. ;        export getbuf
  49. ;        export getlen
  50.         import infile
  51. ;        import last_mat
  52.         export lson
  53. ;        import lson
  54. ;        export match_length
  55. ;        export match_position
  56.         import outfile
  57.         import outfname
  58. ;        import p_code
  59. ;        import p_len
  60.         import printcou
  61. ;        export prnt
  62. ;        export putbuf
  63. ;        export putlen
  64.         import rewind
  65.         export rson
  66. ;        export son
  67.         export text_buf
  68.         export textsize
  69.         export    FileFits
  70.         import    fwrite
  71.  
  72. ; -----------------------------------------------------------------------
  73. ;        Constants
  74. ; -----------------------------------------------------------------------
  75.  
  76. N        equ 4096        ;Buffer size
  77. F        equ 60            ;lookahead buffer size
  78. THRESHOLD    equ 2
  79. N_CHAR        equ 256-THRESHOLD+F    ;kinds of characters (0..N_CHAR-1)
  80. T        equ N_CHAR*2-1        ;size of table
  81. R        equ T-1         ;position of root
  82. NIL        equ    N
  83. FOLD        equ    18
  84. MAX_FREQ    equ    $8000
  85.  
  86.  
  87. ; -----------------------------------------------------------------------
  88. ;        Putc (macro)
  89. ; -----------------------------------------------------------------------
  90.  
  91. outrec:     ds.l    1    ; 0 Speicherzeiger
  92.         ds.l    1    ; 4 Länge
  93.         ds.l    1    ; 8 Basispointer
  94.         ds.l    1    ; 12 basislänge
  95.  
  96. ; Simmuliere turbo-c's fwrite: D0 = 1
  97. ;                   a1 = zeiger auf FILE
  98. ;                a0 = buffer
  99. tcwrite:       ds.w    1
  100. my_fwrite:    move.l    d2,-(sp)
  101.         tst.b    tcwrite
  102.         beq    tc_fwrite
  103.         cmp.w    #1,d0
  104.         bne.b    tc_fwrite
  105.         move.l    (a1),d2
  106.         cmp.l    8(a1),d2
  107.         bne.b    tc_fwrite
  108.         move.w    16(a1),d2
  109.         movem.l d0-d1/a0-a2,-(sp)
  110.         move.l    a0,-(sp)
  111.         move.l    d1,-(sp)
  112.         move.w    d2,-(sp)
  113.         move.w    #$40,-(sp)
  114.         trap    #1
  115.         lea    12(sp),sp
  116.         movem.l (sp)+,d0-d1/a0-a2
  117.         move.l    (sp)+,d2
  118.         rts
  119.  
  120.  
  121.  
  122. tc_fwrite:    move.l    (sp)+,d2
  123.         bra    fwrite
  124.  
  125. shipout:    movem.l d0-a6,-(sp)
  126.         lea    outrec(pc),a0
  127.  
  128.  
  129.         move.l    (a0),d1     ; ptr
  130.         sub.l    8(a0),d1    ; - basis
  131.         beq    ship2        ; Noch nie benutzt!
  132.         move.l    8(a0),a0    ; basis
  133.         move.l    outfile(pc),d0
  134.         beq.b    ship2
  135.         move.l    d0,a1
  136.         moveq.l #1,d0
  137. ;         btst     #0,d1
  138. ;         bcc.b     shipodd     ; schreibe ungerade byteanzahl
  139.         bsr    my_fwrite
  140. ship3:        movea.l outfile(pc),A0
  141.         bsr    ferror        ; if (ferror(outfile))
  142.         tst.w    D0
  143.         beq.b    ship2
  144.         movea.l outfname,A0
  145.         moveq    #$0E,D0
  146.         bsr    error        ; error(WTERR,outfname)
  147.  
  148. ship2:        lea    outrec(pc),a0
  149.         move.l    12(a0),4(a0)
  150.         move.l     8(a0),(a0)
  151.         movem.l (sp)+,d0-a6
  152.         rts
  153.  
  154. ;shipodd:     movem.l d0/d1/a0,-(sp)
  155. ;         subq.l  #1,d1
  156. ;         bsr     my_fwrite
  157. ;         movem.l (sp)+,d0/d1/a0
  158. ;         add.l     d1,a0
  159. ;         subq.l  #1,a0
  160. ;         moveq.l #1,d1
  161. ;         bsr     my_fwrite
  162. ;         bra.b     ship3
  163.  
  164.         macro    fputc reg
  165.         local    putc1
  166.         lea    outrec(pc),a0
  167.         move.l    (a0),a1
  168.         move.b    reg,(a1)+
  169.         move.l    a1,(a0)
  170.         subq.l    #1,4(a0)
  171.         bpl.b  putc1
  172. ; Hier shipout
  173.         bsr    shipout
  174. putc1:
  175.         endm
  176.  
  177.  
  178. OpenOut:    movem.l d0-d3/a0-a2,-(sp)
  179.         move.l    #-1,-(sp)
  180.         move.w    #$48,-(sp); Malloc
  181.         trap    #1
  182.         addq.l    #6,sp
  183.         sub.l    #20000,d0
  184.         move.l    d0,d3
  185.         move.l    d0,-(sp)
  186.         move.w    #$48,-(sp)
  187.         trap    #1
  188.         addq.l    #6,sp
  189.         lea    outrec(pc),a0
  190.         subq.l    #7,d3
  191.         move.l    d0,(a0)+
  192.         move.l    d3,(a0)+
  193.         move.l    d0,(a0)+
  194.         move.l    d3,(a0)+
  195.         movem.l (sp)+,d0-d3/a0-a2
  196.         rts
  197. CloseOut:    bsr    shipout
  198.         move.l    8+outrec(pc),-(sp)
  199.         move.w    #$49,-(sp)
  200.         trap    #1
  201.         addq.l    #6,sp
  202.         rts
  203. ; -----------------------------------------------------------------------
  204. ;        getc (fgetc)
  205. ; -----------------------------------------------------------------------
  206.  
  207.         macro    getc
  208.         local    getc1
  209.         local    getc2
  210.         local    getceof
  211.         move.l    (a0),a1
  212.         cmpa.l    4(a0),a1
  213.         bcc    getc1
  214.         moveq.l #0,d0
  215.         move.b    (a1)+,d0
  216.         move.l    a1,(a0)
  217.         cmp.b    d0,d0        ; set equal flag
  218.         bra.b    getc2
  219. getc1:
  220.         bsr    fgetc
  221.         cmp.w    #$ffff,d0
  222.         beq.b    getceof
  223.         cmp.b    d0,d0        ; set equal-flag
  224.         bra.b    getc2
  225. getceof:    cmp.b    #0,d0        ; set not equal
  226. getc2:
  227.         endm
  228. ; Gets 2 bytes in d7
  229.  
  230.         macro    rgetc
  231.         local    getc1
  232.         local    getc2
  233.         move.l    (a0),a1
  234.         cmpa.l    4(a0),a1
  235.         bcs.b    getc1
  236.         movem.l d1-d2/a0-a2,-(sp)
  237.         bsr    fgetc
  238.         movem.l (sp)+,d1-d2/a0-a2
  239.         bra.b    getc2
  240. getc1:        moveq.l #0,d0
  241.         move.b    (a1)+,d0
  242.         move.l    a1,(a0)
  243. getc2:
  244.         endm
  245. ; Gets 2 bytes in d7
  246.  
  247.         macro    getw
  248.         local    Fits
  249.         local    getwEnd
  250.  
  251.         rgetc
  252.         move.w    d0,d7
  253.         lsl.w    #8,d7
  254.         rgetc
  255.         move.b    d0,d7
  256. getwEnd:
  257.         endm
  258.  
  259.  
  260. ; -----------------------------------------------------------------------
  261. ;        crc_getc
  262. ; -----------------------------------------------------------------------
  263.  
  264.         macro    crcgetc
  265. ; int crc_getc(register FILE *stream)
  266. ; setcrc(ch)
  267.         move.w    crc-lson(a2),D1
  268.         move.w    d1,d2
  269.         eor.w    D0,D1        ; c ^ crc
  270.  
  271.  
  272.         and.w    #$ff,D1     ; & 0xff
  273.         add.w    D1,D1        ; d2=cardinal (crc ^ c) & $ff
  274.  
  275.         lea    crctbl-lson(a2),A1
  276.         lsr.w    #8,D2        ; d0=(crc >> 8)
  277.         move.w    0(A1,D1.w),D1    ; d1=crctbl[(crc ^ (ch)) & 0xff]
  278.         eor.w    D2,D1
  279.         move.w    D1,crc-lson(a2)
  280.         endm
  281.  
  282. ; -----------------------------------------------------------------------
  283. ;        putCode
  284. ; -----------------------------------------------------------------------
  285.  
  286. ; void Putcode(register int l, register int c)
  287.  
  288. ; d7 = putlen
  289. ; register a2 = putlen
  290. ;     -2(a2)=putbuf
  291.         macro    putcode
  292.         local PutCode1
  293.         local PutCode2
  294.         movem.w D3-D4,-(SP)
  295.         move.w    D0,D4
  296.         move.w    D1,D3
  297.         move.b    d7,D2        ; d2=putlen
  298.         lsr.w    D2,D1
  299.         or.w    D1,d6        ; putbuf != c >> putlen
  300.  
  301.         add.b    D0,d7        ; putlen+=l
  302.         cmpi.b    #8,d7        ; putlen
  303.         bcs    PutCode2
  304.  
  305.         move.w    d6,D0        ; putbuf
  306.         lsr.w    #8,D0
  307.         fputc    d0        ; putc(putbuf,outfile)
  308. ; if ((putlen -= 8) >=8)
  309.         subq.b    #8,d7        ; putlen
  310.         cmpi.b    #8,d7        ; putlen
  311.         bcs.b    PutCode1
  312.  
  313.         fputc    d6        ; putc(putbuf,outfile)
  314.         addq.l    #2,codesize    ; codesize+=2
  315.         subq.b    #8,d7        ;putlen-=8
  316.  
  317.         move.w    D3,D0
  318.         move.b    D4,D1
  319.         sub.b    d7,D1        ; putlen
  320.         lsl.w    D1,D0
  321.         move.w    D0,d6        ; putbuf = c << (l-putlen)
  322.         bra.b    PutCode2
  323.  
  324. PutCode1:    move.w    d6,D0        ; putbuf
  325.         lsl.w    #8,D0
  326.         move.w    D0,d6        ; putbuf <<=8
  327.         addq.l    #1,codesize    ; codesize++
  328. PutCode2:    movem.w (SP)+,D3-D4
  329.         endm
  330.  
  331. ; -----------------------------------------------------------------------
  332. ;       Reconstract a tree
  333. ; -----------------------------------------------------------------------
  334.  
  335. reconst:    movem.l D0-A6,-(SP)
  336.         lea    freq,A0
  337.         lea    prnt-freq(a0),A1
  338.         lea    son-freq(a0),A2
  339.         bra.b    rcon_a
  340.  
  341. rcon:        movem.l D0-A6,-(SP)
  342. rcon_a:     moveq    #0,D0
  343.         moveq    #0,D1
  344. ; Collect leaf nodes in the first half of the table
  345. ; and relace the freq by (freq+1)/2
  346. rcon1:        cmpi.w    #2*T,0(A2,D1.w) ; if son[i] >= T
  347.         blt.b    rcon2
  348.         moveq    #1,D2
  349.         add.w    0(A0,D1.w),D2
  350.         lsr.w    #1,D2
  351.         move.w    D2,0(A0,D0.w)    ; freq[j] = (freq[i]+1)/2
  352.         move.w    0(A2,D1.w),0(A2,D0.w) ; son[j]=son[i]
  353.         addq.w    #2,D0        ; j++
  354. rcon2:        addq.w    #2,D1        ; i++
  355.         cmp.w    #2*T,D1     ; i < T
  356.         blo.b    rcon1
  357.  
  358. ; begin constructing tree by connecting sons
  359. ; for (i=0; j=N_CHAR; j < T; i+=2; j++) {
  360.  
  361.         move.w    #N_CHAR*2,D3
  362.         moveq    #0,D4
  363. rcon3:        moveq    #2,D0
  364.         add.w    D4,D0        ;       k=i+2
  365.         move.w    0(A0,D4.w),D6
  366.         add.w    0(A0,D0.w),D6    ; f=freq[i]+freq[k]
  367.         move.w    D6,0(A0,D3.w)    ; freq[j]=f
  368. ; for (k=j-1; f < freq[k]; k--);
  369.         moveq    #-2,D5
  370.         add.w    D3,D5
  371.         bra.b    rcon5
  372. rcon4:        subq.w    #2,D5
  373. rcon5:        cmp.w    0(A0,D5.w),D6
  374.         blo.b    rcon4
  375.  
  376.         addq.w    #2,D5
  377.         move.w    D3,D7
  378.         sub.w    D5,D7        ; l=(j-k) * 2
  379.  
  380.         lea    0(A0,D5.w),A3
  381.         bsr.b    movemem     ;nach oben schieben
  382.         move.w    D6,0(A0,D5.w)    ; freq[k]= f
  383.  
  384.         lea    0(A2,D5.